#include <string.h>

#include "at_client.h"
#include "qcloud_iot_api_export.h"
#include "cat1.h"
#include "params_config.h"

static void cat1_mqtt_conn_ack_func(const char *data, uint32_t size)
{
    setFlag(MQTT_CON_FLAG);
}

static void cat1_mqtt_sub_ack_func(const char *data, uint32_t size)
{
    setFlag(MQTT_SUB_FLAG);
}

static void cat1_mqtt_recv_sub_msg_func(const char *data, uint32_t size)
{
    parse_node_info(data, size);
}


static void cat1_mqtt_pub_ack_func(const char *data, uint32_t size)
{
    setFlag(MQTT_PUB_FLAG);
}

at_urc cat1_urc_table[] = {
        {"CONNE",  "\r\n", cat1_mqtt_conn_ack_func},
        {"SUBACK", "\r\n", cat1_mqtt_sub_ack_func},
        {"+MSUB:", "\r\n", cat1_mqtt_recv_sub_msg_func},
        {"PUBACK", "\r\n", cat1_mqtt_pub_ack_func},
};



/**
 *  @brief  检查模组是否准备好
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 */
static int cat1_check_ready(void)
{
    int cnt = 0;
    int ret = -1;
    at_response_t resp = NULL;

    resp = at_create_resp(16, 0, CMD_TIMEOUT_MS);   // 创建一个AT
    while (cnt++ < 10) {
        if(QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT\r\n")) {
            ret = 0;
            break;
        }
    }

	if(resp) {
		at_delete_resp(resp);
	}

    return ret;
}


/**
 *  @brief  检查模组SIM卡是否正常
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   AT+CPIN?\r\n\r\n+CPIN: READY\r\n\r\nOK\r\n
 */
static int cat1_sim_card_check(void)
{
    int cnt = 0;
    int ret = -1;
    at_response_t resp = NULL;
    
    create_expected_ack_date("READY", strlen("READY"));   
    
    resp = at_create_resp(32, 3, CMD_TIMEOUT_MS);   // 创建一个AT
    while (cnt++ < 10) {
        if(QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+CPIN?\r\n")) {
                ret = 0;
                break;
        }
    }

	if(resp) {
		at_delete_resp(resp);
	}

    return ret;
}


/**
 *  @brief  检查模组GPRS附着状态
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   AT+CGATT?\r\n\r\n+CGATT: 1\r\n\r\nOK
 */
static int cat1_check_GPRS_attached_status(void)
{
    int cnt = 0;
    int ret = -1;
    at_response_t resp = NULL;
    
    create_expected_ack_date("+CGATT: 1", strlen("+CGATT: 1"));   
    
    resp = at_create_resp(32, 3, CMD_TIMEOUT_MS);   // 创建一个AT
    while (cnt++ < 10) {
        if(QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+CGATT?\r\n")) {
                ret = 0;
                break;
        }
    }

	if(resp) {
		at_delete_resp(resp);
	}

    return ret;
}


/**
 *  @brief  检查模组网络注册状态
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   AT+CGREG?\r\n\r\n+CGREG: 0,1\r\n\r\nOK\r\n
 */
static int cat1_check_network_register_status(void)
{
    int cnt = 0;
    int ret = -1;
    at_response_t resp = NULL;
    
    create_expected_ack_date("+CGREG: 0,1", strlen("+CGREG: 0,1"));   
    
    resp = at_create_resp(32, 3, CMD_TIMEOUT_MS);   // 创建一个AT
    while (cnt++ < 10) {
        if(QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+CGREG?\r\n")) {
                ret = 0;
                break;
        }
    }

	if(resp) {
		at_delete_resp(resp);
	}

    return ret;
}



/**
 *  @brief  MQTT配置
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   AT+MCONFIG="***","***","***"\r\n\r\nOK\r\n
 */
static int cat1_mqtt_config(void)
{
    int cnt = 0;
    int ret = -1;
    at_response_t resp = NULL;

    resp = at_create_resp(192, 0, CMD_TIMEOUT_MS);   // 创建一个AT
    while (cnt++ < 10) {
        if(QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+MCONFIG=\"%s\",\"%s\",\"%s\"\r\n", MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) {
                ret = 0;
                break;
        }
    }

	if(resp) {
		at_delete_resp(resp);
	}

    return ret;
}



/**
 *  @brief  MQTT连接服务器
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   AT+MIPSTART="***","***"\r\n\r\nOK\r\n
 */
static int cat1_mqtt_connect(void)
{
    int cnt = 0;
    int ret = -1;
    at_response_t resp = NULL;
    
    clearFlag(MQTT_CON_FLAG);
            
    resp = at_create_resp(128, 0, CMD_TIMEOUT_MS);   // 创建一个AT
    while (cnt++ < 10) {
        if(QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+MIPSTART=\"%s\",\"%s\"\r\n", MQTT_SERVEP_IP, MQTT_SERVER_PORT)) {
                ret = 0;
                break;
        }
    }

	if( waitFlag(MQTT_CON_FLAG, 3000) == false )
	{
		ret = -1;
	}

	if(resp)
	{
		at_delete_resp(resp);
	}

    return ret;
}


/**
 *  @brief  MQTT订阅主题
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   AT+MSUB="/a1GpCYF1mlC/Air724/user/get",0
 */
int cat1_mqtt_sub(void)
{
	at_response_t resp = NULL;
    int ret = -1;
    int cnt = 0;
    
    clearFlag(MQTT_SUB_FLAG);
    
	resp = at_create_resp(64, 0, CMD_TIMEOUT_MS);   // 创建一个AT	
    
    while (cnt++ < 10) {
        if( QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+MSUB=\"%s\",%d\r\n", MQTT_SUB_TOPIC_NAME, MQTT_QOS_LEVEL) ) {
            ret = 0;
            break;
        }
    }
    
    if( waitFlag(MQTT_SUB_FLAG, 3000) == false )
	{
		ret = -1;
	}
    
	if(resp) {
		at_delete_resp(resp);
	}    
	
	return ret;
}


/**
 *  @brief  MQTT发布消息
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   
 */
int cat1_mqtt_pub_msg(char *send_msg)
{
	at_response_t resp = NULL;
    int ret = -1;
    int cnt = 0;
    
    clearFlag(MQTT_PUB_FLAG);
    
	resp = at_create_resp(256, 0, CMD_TIMEOUT_MS);   // 创建一个AT	
    
    while (cnt++ < 10) {
        if( QCLOUD_RET_SUCCESS == 
           at_exec_cmd(resp, "AT+MPUB=\"%s\",%d,%d,\"%s\"\r\n", MQTT_PUB_TOPIC_NAME, MQTT_QOS_LEVEL, MQTT_RETAIN, send_msg) ) {
               ret = 0;
               break;
           }
    }
    
    if( waitFlag(MQTT_PUB_FLAG, 3000) == false )
	{
		ret = -1;
	}
    
	if(resp) {
		at_delete_resp(resp);
	}    
	
	return ret;
}


/**
 *  @brief  MQTT发送心跳包
 *  @param  无
 *  @retval 成功返回0，失败返回-1
 *  @note   
 */
int cat1_mqtt_send_heartbeat(void)
{
	at_response_t resp = NULL;
    int ret = -1;
    int cnt = 0;
      
    create_expected_ack_date("+MQTTSTATU :1", strlen("+MQTTSTATU :1"));   
    
	resp = at_create_resp(32, 1, CMD_TIMEOUT_MS);   // 创建一个AT	
    
    while (cnt++ < 10) {
        if( QCLOUD_RET_SUCCESS == at_exec_cmd(resp, "AT+MQTTSTATU\r\n") ) {
               ret = 0;
               break;
           }
    }
    
	if(resp) {
		at_delete_resp(resp);
	}    
	
	return ret;
}


/**
 *  @brief  freertos AT框架初始化
 *  @params 无
 *  @retval 成功返回0，失败返回-1
 *  @note   增加的at框架初始化函数
 */
int fos_at_init(void)
{
    eAtResault ret = QCLOUD_RET_SUCCESS;
    at_client_t p_client;    
    
    p_client = at_client_get();     // 获取 at_client_t 对象
	if(NULL == p_client) {
		goto err; 
	}
    
    /* register URC data execution function  */
    at_set_urc_table(p_client, cat1_urc_table, sizeof(cat1_urc_table) / sizeof(cat1_urc_table[0]));
    
    ret = at_client_init(p_client); // 初始化 at_client_t 对象
	if(QCLOUD_RET_SUCCESS != ret) {
		goto err;
	}

    return 0;
    
err:
    return -1;
}


/**
 *  @brief  CAT1 模组初始化
 *  @params 无
 *  @retval 成功返回0，失败返回-1
 */
int cat1_module_init(void)
{
    At_Log_Set_Level(LOG_NONE);     // 设置输出日志的等级
    
    if( fos_at_init() != 0)         // 初始化AT框架
        return -1;
    
    if( cat1_check_ready() != 0 )   // 检查模组是否准备好
        return -1;
    
    if( cat1_sim_card_check() != 0 )    // 检查SIM卡状态
        return -1;
    
    if( cat1_check_GPRS_attached_status() != 0 )    // 检查GPRS的附着状态
        return -1;
    
    if( cat1_check_network_register_status() != 0 ) // 检查网络注册状态
        return -1;
    
    if( cat1_mqtt_config() != 0 )   // MQTT配置
        return -1;
    
    if( cat1_mqtt_connect() != 0)   // 连接服务器
        return -1;
    
    if( cat1_mqtt_sub() != 0 )
        return -1;
    
    if( cat1_mqtt_pub_msg("adssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss \r\n\
                          adssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss \r\n\
                              adssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss") != 0 )
                                  return -1;
                          
    if( cat1_mqtt_send_heartbeat() != 0 )
        return -1;
    
    return 0;
}

